
#import "XLoading.h"

#import <QuartzCore/QuartzCore.h>

#import "XDefine.h"
#import "XMacro.h"
#import "XLayerController.h"
#import "UIColor+X.h"
#import "UIView+X.h"


#define FILTER_FRAME                    CGRectMake(10,10,70,70)

#define FILTER_COLOR                    [UIColor colorWithRed:0xd7 / 255.0f \
                                                        green:0x54 / 255.0f \
                                                         blue:0x36 / 255.0f \
                                                        alpha:1.0f]


const static NSTimeInterval PROGRESS_INTERVAL = 0.1f;
const static float          PROGRESS_STEP     = 0.1f;


static NSString *PROGRESS_FRONTIMAGE    = @"DracodeSDK_iconProgress.png";


XLoading *g_loading = nil;


@implementation XLoading


/**
 * 单例对象
 * @result
 */
+ (instancetype)si {
    @synchronized (self) {
        if (nil == g_loading) {
            g_loading = [[XLoading alloc] init];
        }
    }
    
    return g_loading;
}


/**
 * 初始化
 * @result              id 类型，ProgressHelper 对象
 */
- (id)init {
    self = [super init];
    if (self) {
        // 修改样式
        self.backgroundColor = [UIColor colorWithHex:0x000000 andAlpha:0.5];
        
        CGRect rcWindow = [[UIScreen mainScreen] bounds];
        CGRect rc = CGRectMake((rcWindow.size.width - 100) / 2, (rcWindow.size.height - 100) / 2, 100, 100);
        self.frame = rc;
        
        [self addCornerBorderWithColor:[UIColor clearColor]];
        
        // 加载进度菊花
        rc.origin = CGPointZero;
        rc = CGRectInset(rc, 10, 10);
        UIActivityIndicatorView *aiv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
        aiv.frame = rc;
        [aiv startAnimating];
        [self addSubview:aiv];
    }
    return self;
}


/**
 * UIView 转图片
 * @param   v           UIView 类型，需要转换成image的视图
 * @result              UIImage 类型，转换出来的 UIImage 对象
 */
- (UIImage*)convertViewToImage:(UIView*)v {
    UIGraphicsBeginImageContext(v.bounds.size);
    [v.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
#pragma mark     -
#pragma mark     带有提示信息的进度条
/**
 * 加载进度图片数组
 * @param        container，需要填充图片数组的UIImageView
 * @result
 */
NSInteger const FILTER_STEP_COUNT                   = 10;
- (void)loadingImagesFor:(UIImageView *) container {
    // 加载背景图
    CGRect rc = container.frame;
    rc.origin = CGPointZero;
    rc.size.width *= 2;
    rc.size.height *= 2;
    UIView *vBG = [[UIView alloc] initWithFrame:rc];
    vBG.backgroundColor = [UIColor clearColor];
    
    // 处理中间的进度
    rc.origin = CGPointMake(10, 10);
    rc.size = CGSizeMake(vBG.frame.size.width - 20, vBG.frame.size.height - 20);
    UIView *vFilterBG = [[UIImageView alloc] initWithFrame:rc];
    vFilterBG.backgroundColor = [UIColor darkGrayColor];
    [vBG addSubview:vFilterBG];
    
    UIView *vFilter = [[UIView alloc] initWithFrame:rc];
    vFilter.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"DracodeSDK_MsgBoxTitleBG.png"]];
    [vBG addSubview:vFilter];
    
    // 加载前景镂空图
    rc = vBG.frame;
    UIImageView *ivFront = [[UIImageView alloc] initWithFrame:rc];
    ivFront.backgroundColor = [UIColor clearColor];
    ivFront.image = [UIImage imageNamed:PROGRESS_FRONTIMAGE];
    [vBG addSubview:ivFront];
    
    // 处理进度的动画集
    NSMutableArray *arrImages = [[NSMutableArray alloc] initWithCapacity:0];
    CGFloat fStepHeight = vBG.frame.size.height / FILTER_STEP_COUNT;
    for (NSInteger i = 0; i < FILTER_STEP_COUNT + 1; i++) {
        rc = vFilterBG.frame;
        rc.size.height = fStepHeight * i;
        rc.origin.y = vFilterBG.frame.size.height - rc.size.height;
        vFilter.frame = rc;
        
        UIImage *img = [self convertViewToImage:vBG];
        [arrImages addObject:img];
    }
    container.animationImages = arrImages;
}

/**
    显示带标题的滚动进度条时，进行UI调整
    @param title，滚动进度条上要显示的标题
 */
- (void)adjustWithTitle:(NSString*)title
{
    CGSize screen = [UIScreen mainScreen].bounds.size;
    
    // 计算宽度
    UIFont *font = [UIFont fontWithName:@"Helvetica" size:14.0f];
    CGSize restrictSize = CGSizeMake(screen.width, 30);
    CGSize size = [title sizeWithFont:font constrainedToSize:restrictSize];
    float titleWidth = size.width;                  // 标题宽度
    float margin = 5;                               // 标题左右边距
    float topMargin = 10;                           // 菊花的上边距
    float fixed = 100;                              // 菊花最外层默认宽度
    float width = titleWidth + 2 * margin;          // 菊花在有标题的情况下的新宽度
    width = width < fixed ? fixed : width;
    
    // 调整最外层的frame
    CGRect frame = self.frame;
    frame.size.width = width;
    frame.size.height = topMargin + width/2.0f + restrictSize.height;
    frame.origin.x = (screen.width - width) / 2.0f;
    frame.origin.y = (screen.height - frame.size.height)/2.0f;
    self.frame = frame;
    
    // 调整菊花frame
    UIActivityIndicatorView *vIndicator = nil;
    NSArray *arrSub = [self subviews];
    for (id v in arrSub) {
        if ([v isKindOfClass:[UIActivityIndicatorView class]]) {
            vIndicator = v;
            break;
        }
    }
    frame = vIndicator.frame;
    frame.origin.x = width/4.0f;
    frame.origin.y = topMargin;
    frame.size = CGSizeMake(width/2.0f, width/2.0f);            // 菊花宽高均为最外层的宽度的一半
    vIndicator.frame = frame;
    
    // 添加标题
    UILabel *label = nil;
    for (id v in arrSub) {
        if ([v isKindOfClass:[UILabel class]]) {
            label = v;
            break;
        }
    }
    if (label == nil) {
        // 创建
        label = [[UILabel alloc] initWithFrame:CGRectMake((width-titleWidth)/2.0f, topMargin + frame.size.height, titleWidth, restrictSize.height)];
        label.font = font;
        label.backgroundColor = [UIColor clearColor];
        label.textColor = [UIColor whiteColor];
        label.textAlignment = UITextAlignmentLeft;
        [self addSubview:label];
    }
    label.text = title;
}

/**
    当要显示的进度条不带提示信息时，进行的UI复位
 */
- (void)reset
{
    // 移除标题
    NSArray *arrSub = self.subviews;
    UILabel *label = nil;
    for (id v in arrSub) {
        if ([v isKindOfClass:[UILabel class]]) {
            label = v;
            break;
        }
    }
    [label removeFromSuperview];
    // 恢复固定大小
    CGRect frame = self.frame;
    CGSize screen = [UIScreen mainScreen].bounds.size;
    frame.origin.x = (screen.width - 100) / 2.0f;
    frame.origin.y = (screen.height - 100)/2.0f;
    frame.size = CGSizeMake(100, 100);
    self.frame = frame;
    // 菊花重新居中
    UIActivityIndicatorView *vIndicator = nil;
    for (id v in arrSub) {
        if ([v isKindOfClass:[UIActivityIndicatorView class]]) {
            vIndicator = v;
            break;
        }
    }
    frame = vIndicator.frame;
    frame.size.width = self.frame.size.width/2.0f;
    frame.size.height = frame.size.width;
    frame.origin.x = frame.size.width/2.0f;
    frame.origin.y = frame.origin.x;
    vIndicator.frame = frame;
}

- (void)setTitle:(NSString*)title
{
    if (title!=(id)[NSNull null] && title.length) {
        [self adjustWithTitle:title];
    }
    else {
        [self reset];
    }
}

/**
 * 显示加载进度条（循环滚动）
 * @param       title，需要提示的标题信息
 * @result
 *
 */
- (void)showWithTitle:(NSString *)title {
    [self setTitle:title];
    [XLayerController addLayer:self withFocus:NO andBackgroundClose:NO];
}
#pragma mark     -

/**
 * 隐藏加载进度条
 */
- (void)hide {
    [XLayerController removeLayer:self];
}


/**
 * 销毁
 */
- (void)dealloc {
    if (self == g_loading) {
        g_loading = nil;
    }
}


/**
 * 显示加载进度条（循环滚动显示）
 * @result
 */
+ (void)show {
    if (nil == g_loading) {        // 因为LoadingView只会被加入一个
        [[XLoading si] showWithTitle:nil];
    }
}


/**
 * 显示加载进度条含提示信息
 * @param       title，需要提示的标题信息
 * @result
 */
+ (void)showWithTitle:(NSString *)title {
    if (nil == g_loading) {        // 因为LoadingView只会被加入一个
        [[XLoading si] showWithTitle:title];
    }
}


/**
 * 隐藏加载进度条
 * @result
 */
+ (void)hide {
    if (g_loading) {        // 因为LoadingView只会被加入一个，所以 hide 的时候，也只 hide 一个
        [[XLoading si] hide];
        g_loading = nil;
    }
}


@end

